import base64
import http
import json
import logging
import threading
import uuid

from django.utils.deprecation import MiddlewareMixin
from rest_framework import response as rest_response

local = threading.local()  # 获取当前线程对象

logger = logging.getLogger("info")
error_logger = logging.getLogger("error")


class RequestLogFilter(logging.Filter):
    """
    日志过滤器，将当前请求线程的request信息保存到日志的record上下文
    record带有formater需要的信息。
    """

    def filter(self, record):
        record.method = getattr(local, 'method', "none")
        record.path = getattr(local, 'path', "none")
        record.request_id = getattr(local, 'request_id', "none")
        record.params = getattr(local, 'params', "none")
        record.body = getattr(local, 'body', "none")
        record.user = getattr(local, 'user', "none")
        return True


class RequestLogMiddleware(MiddlewareMixin):
    """
    将request的信息记录在当前的请求线程上。
    """
    def process_request(self, request):
        # 以下逻辑是 实现请求进来打印 相关请求参数
        local.request_id = str(uuid.uuid1())  # 线程对象里面加入uuid
        body = {}
        try:
            body = request.body.decode()
            if body:
               body = json.loads(body)
        except:
            pass
        token = request.META.get("HTTP_AUTHORIZATION")
        local.user = "guest"
        if token:
            try:
                user_base64 = token.split(".")[1]
                missing_padding = 4 - len(user_base64) % 4
                if missing_padding:
                    user_base64 += '=' * missing_padding

                local.user = str(base64.b64decode(bytes(user_base64, 'utf-8')), encoding='utf-8')
            except:
                local.user = token
                pass

        local.method = request.method
        local.params = request.GET.dict()
        local.path = request.path_info
        local.body = json.dumps(body)

        request_info = {
            "request_id": local.request_id,
            'method': request.method,
            'path': request.path_info,
            'params': request.GET.dict(),
            'body': body,
            'user': local.user,
        }

        logger.info(f'requests: {json.dumps(request_info, ensure_ascii=False)}')

# def process_response(self, request, response):
    #     """
    #     在执行完View函数准备将响应发到客户端前被执行 / 响应结果写入日志
    #     这里是打印 响应数据的日志，多加了几个 if 判断
    #     """
    #     path = request.path_info
    #
    #     if isinstance(response, rest_response.Response) or isinstance(response, http.JsonResponse):
    #         if response.content and path not in filter_path:
    #             logger.info(f'response: {response.content.decode("utf-8")}')
    #     elif isinstance(response, http.HttpResponseNotFound):
    #         # 资源不存在
    #         error_data = {
    #             'status': 'error',
    #             'message': f'not found "{path}"'
    #         }
    #         logger.error(json.dumps(error_data, ensure_ascii=False))
    #         response = http.JsonResponse(data=error_data)
    #     else:
    #         # 未处理异常
    #         error_data = {
    #             'status': 'error',
    #             'message': '{0}'.format(str(response))
    #         }
    #         logger.error(json.dumps(error_data, ensure_ascii=False))
    #         response = http.JsonResponse(data=error_data)
    #     return response


class ExceptionLoggingMiddleware(MiddlewareMixin):
    def process_exception(self, request, exception):
        import traceback
        error_logger.error(traceback.format_exc())